<template>
	<div class="app-mob-color-picker-wrapper" ref="appMobColorPicker">
		<div class="color-pick-wrapper" ref="colorPick">
			<div class="color-pick-wrapper__content">
				<div
					class="color-board"
					ref="colorBoard"
					@mousedown="handleBoardDown"
					@mouseup="handleBoardUp"
					@mousemove.prevent="handleBoardMove"
					@mouseleave="handleBoardOut"
					@touchstart="handleBoardDownApp"
					@touchmove="handleBoardMoveApp"
				>
					<div class="color-point" ref="colorPoint">
						<div class="shape"></div>
					</div>
					<div class="bg bg1"></div>
					<div class="bg bg2"></div>
				</div>
				<div
					class="color-bar"
					ref="colorBar"
					@mousedown="handleBarDown"
					@mouseup="handleBarUp"
					@mousemove.prevent="handleBarMove"
					@mouseleave="handleBarOut"
					@touchstart="handleBarDownApp"
					@touchmove="handleBarMoveApp"
				>
					<div class="color-rect">
						<div class="shape"></div>
					</div>
					<div class="bg"></div>
				</div>
				<div class="color-transparency" v-show="showAlpha">
					<div
						class="color-transparency-backgre"
						ref="colorTransparency"
						@mousedown="handleTransparencyDown"
						@mouseup="handleTransparencyUp"
						@mousemove.prevent="handleTransparencyMove"
						@mouseleave="handleTransparencyOut"
						@touchstart="handleTransparencyDownApp"
						@touchmove="handleTransparencyMoveApp"
					>
						<div class="color-rect">
							<div class="shape"></div>
						</div>
						<div
							class="bg"
							:style="{
								background,
							}"
						></div>
					</div>
				</div>
				<div class="color-display" ref="colorDisplay">
					<input class="color-value" v-model="colorValue" />
					<div class="color-Block"></div>
				</div>

				<div class="view-footer__buttons footer__buttons color-pick__switch">
					<AppButton @click="handleClose">{{
						$t('app.common.cancel', '取消')
					}}</AppButton>
					<AppButton type="primary" @click="handleDetermine">{{
						$t('app.common.confirm', '确认')
					}}</AppButton>
				</div>
			</div>
		</div>
	</div>
</template>
<script setup lang="ts">
import { ref, onMounted, watch } from 'vue';

const emit = defineEmits([
	'wrapperDetermineChange',
	'wrapperClose',
	'wrapperChange',
]);
const props = defineProps([
	'colorFormat',
	'showAlpha',
	'color',
	'pickerClientWidth',
	'pickerClientHeight',
]);

interface IColorObj {
	r: number;
	g: number;
	b: number;
	a?: number;
}

/**
 * 用于获取dom元素
 * @appMobColorPicker 用于获取整个颜色选择器的dom元素
 * @colorBoard 用于获取颜色板的dom元素
 * @colorPoint 用于获取颜色板选择器的dom元素
 * @colorBar 用于获取颜色条的dom元素
 * @colorTransparency 用于获取透明度条的dom元素
 * @colorPick 用于获取颜色选择器的dom元素
 * @colorDisplay 用于获取颜色显示器的dom元素
 */
const appMobColorPicker = ref<HTMLElement | null>(null);
const colorBoard = ref<HTMLElement | any>(null);
const colorPoint = ref<HTMLElement | null>(null);
const colorBar = ref<HTMLElement | any>(null);
const colorTransparency = ref<HTMLElement | null>(null);
const colorPick = ref<HTMLElement | null>(null);
const colorDisplay = ref<HTMLElement | null>(null);
/**
 * 用于显示颜色信息
 * @colorValue 用于显示颜色值
 * @background 用于显示透明度条的背景色
 */
let colorValue = ref<string>('');
let background = ref<string>('');

/**
 * 用于计算的变量
 * @boardWidth 颜色板的宽度
 * @boardHeight 颜色板的高度
 * @boardOffsetLeft 颜色板的左偏移量
 * @boardOffsetTop 颜色板的上偏移量
 * @barWidth 颜色条的宽度
 * @barOffsetLeft 颜色条的左偏移量
 * @transparencyWidth 透明度条的宽度
 * @transparencyOffsetLeft 透明度条的左偏移量
 * @colorNumber 用于保存颜色值
 */
let boardWidth: number;
let boardHeight: number;
let boardOffsetLeft: number;
let boardOffsetTop: number;
let barWidth: number;
let barOffsetLeft: number;
let transparencyWidth: number;
let transparencyOffsetLeft: number;
let colorNumber: string;

/**
 * 保存选中的rgb颜色
 */
let resColorRgb = {
	r: 0,
	g: 0,
	b: 0,
};

/**
 * 用于标记是否正在拖动
 * @barIsDragging 标记颜色条是否正在拖动
 * @barOffsetX 鼠标指针在 div 元素内的偏移量
 */
let barIsDragging = false; // 标记是否正在拖动
let barOffsetX = 0; // 鼠标指针在 div 元素内的偏移量

/**
 * 用于标记是否正在拖动
 * @boardIsDragging 标记颜色板是否正在拖动
 * @boardOffsetX 鼠标指针在 div 元素内的偏移量
 * @boardOffsetY 鼠标指针在 div 元素内的偏移量
 */
let boardIsDragging = false;
let boardOffsetX = 0;
let boardOffsetY = 0;

/**
 * 用于标记是否正在拖动
 * @transparencyIsDragging 标记透明度条是否正在拖动
 * @transparencyOffsetX 鼠标指针在 div 元素内的偏移量
 */
let transparencyIssDragging = false; // 标记是否正在拖动
let transparencyOffsetX = 0; // 鼠标指针在 div 元素内的偏移量

/**
 * 用于保存颜色值
 * @Hue 色调
 * @Saturation 饱和度
 * @Value 明度
 * @transparency 透明度
 */
let [Hue, Saturation, Value, transparency] = [0, 0, 1, 1];

const init = () => {
	appMobColorPicker.value.style.height = props.pickerClientHeight + 'px'; //设置颜色选择器弹框的高度
	colorBoard.value.style.height = props.pickerClientWidth - 16 * 2 + 2 + 'px'; //设置颜色板的高度

	colorBoard.value.style.backgroundColor = `rgb(255, 0, 0)`; //设置颜色板的初始背景色
	boardWidth = colorBoard.value.offsetWidth || 0; //获取颜色板的宽度
	boardHeight = colorBoard.value.offsetHeight || 0; //获取颜色板的高度
	boardOffsetLeft = colorBoard.value.getBoundingClientRect().left || 0; //获取颜色板的左偏移量
	boardOffsetTop = colorBoard.value.getBoundingClientRect().top || 0; //当浏览器缩小时就不能拿到值了
	barWidth = colorBar.value.offsetWidth || 0; //获取颜色条的宽度
	barOffsetLeft = colorBar.value.getBoundingClientRect().left || 0; //获取颜色条的左偏移量
	transparencyWidth = colorTransparency.value.offsetWidth || 0; //获取透明度条的宽度
	transparencyOffsetLeft =
		colorTransparency.value.getBoundingClientRect().left || 0; //获取透明度条的左偏移量

	colorPoint.value?.setAttribute(
		'style',
		`left: ${0}px; top: ${boardHeight}px;`
	); // 设置颜色选择器的初始位置
	colorTransparency.value
		?.querySelector('.color-rect')
		?.setAttribute('style', `left: ${transparencyWidth}px;`); // 设置透明度条的初始位置
	initColor(props.color); // 初始化颜色
};

/**
 * 初始化颜色
 * @param resColor 颜色值
 * @param tr 透明度
 */
function initColor(resColor: string, tr?: number) {
	colorNumber = resColor; // 保存颜色值
	colorDisplay.value
		?.querySelector('.color-Block')
		.setAttribute('style', `background: ${resColor};`); // 设置颜色显示块的背景色
	colorValue.value = colorNumber ? colorNumber : resColor; // 设置颜色值
	let rgbValue: any = ifHexOrRgbObject(resColor); // 获取rgb值
	background.value = getBackground(rgbValue.r, rgbValue.g, rgbValue.b); // 设置颜色板的背景色
	// 服务器传递的在这里赋初始值
	resColorRgb.r = rgbValue.r;
	resColorRgb.g = rgbValue.g;
	resColorRgb.b = rgbValue.b;
	handleColorEcho(rgbValue); // 处理颜色回显位置
}

/**
 * 按下颜色条事件
 * @param e
 */
function handleBarDownApp(e: any) {
	barIsDragging = true;
	barOffsetX = e.touches[0].offsetX;

	let X = e.touches[0].clientX - barOffsetLeft;
	barChangeApp(e, barOffsetX, X);
}

/**
 * 拖动颜色条事件
 * @param e
 */
function handleBarMoveApp(e: any) {
	if (barIsDragging) {
		let X = e.touches[0].clientX - barOffsetLeft; // 获取鼠标指针在 div 元素内的偏移量
		barChangeApp(e, barOffsetX, X); // 调用颜色条改变事件
	}
}

/**
 * 按下颜色板事件
 * @param e
 */
function handleBoardDownApp(e: any) {
	boardIsDragging = true;
	boardOffsetX = e.touches[0].offsetX;
	boardOffsetY = e.touches[0].offsetY;
	let X = e.touches[0].clientX - boardOffsetLeft;
	let Y = e.touches[0].clientY - boardOffsetTop;
	pointChangeApp(e, boardOffsetX, X, boardOffsetY, Y);
}

/**
 * 拖动颜色板事件
 * @param e
 */
function handleBoardMoveApp(e: any) {
	if (boardIsDragging) {
		let X = e.touches[0].clientX - boardOffsetLeft;
		let Y = e.touches[0].clientY - boardOffsetTop;
		pointChangeApp(e, boardOffsetX, X, boardOffsetY, Y);
	}
}

/**
 * 按下透明度条事件
 */
function handleTransparencyDownApp(e: any) {
	transparencyIssDragging = true;
	transparencyOffsetX = e.touches[0].offsetX;
	let X = e.touches[0].clientX - transparencyOffsetLeft;
	transparencyChangeApp(e, transparencyOffsetX, X);
}

/**
 * 拖动透明度条事件
 * @param e
 */
function handleTransparencyMoveApp(e: any) {
	if (transparencyIssDragging) {
		let X = e.touches[0].clientX - transparencyOffsetLeft;
		transparencyChangeApp(e, transparencyOffsetX, X);
	}
}

/**
 * 颜色条改变
 * @param e	事件
 * @param offsetX	鼠标指针在 div 元素内的偏移量
 * @param x	鼠标指针在 div 元素内的偏移量
 */
function barChangeApp(e: any, offsetX?: any, x?: any) {
	let tx = offsetX ? offsetX : e.touches[0].clientX;
	let X = x ? x : tx - barOffsetLeft;
	let leftX = X <= 0 ? 0 : X >= barWidth ? barWidth : X;
	colorBar.value
		?.querySelector('.color-rect')
		?.setAttribute('style', `left: ${leftX}px;`);
	Hue = leftX / barWidth;
	let bgColor = HSVtoRGB(Hue, 1, 1);
	colorBoard.value.style.backgroundColor = `rgb(${bgColor.r}, ${bgColor.g}, ${bgColor.b})`;
	resultChange(HSVtoRGB(Hue, Saturation, Value), 1);
	colorPoint.value?.setAttribute(
		'style',
		`left: ${boardWidth}px; top: ${0}px;`
	);
	pointChange({}, boardWidth, boardWidth, 0, '0');
}

/**
 * 颜色板选取变化
 * @param e	事件
 * @param offsetX	鼠标指针在 div 元素内的偏移量
 * @param x	鼠标指针在 div 元素内的偏移量
 * @param offsetY	鼠标指针在 div 元素内的偏移量
 * @param y	鼠标指针在 div 元素内的偏移量
 */
function pointChangeApp(
	e: any,
	offsetX?: any,
	x?: any,
	offsetY?: any,
	y?: any
) {
	let tx = offsetX ? offsetX : e.touches[0].clientX;
	let ty = offsetY ? offsetY : e.touches[0].clientY;
	let X = x ? x : tx - boardOffsetLeft;
	let Y = y ? y : ty - boardOffsetTop / 2;
	let leftX = X <= 0 ? 0 : X >= boardWidth ? boardWidth : X;
	let leftY = Y <= 0 ? 0 : Y >= boardHeight ? boardHeight : Y;
	colorPoint.value?.setAttribute('style', `left: ${leftX}px; top: ${leftY}px;`);
	Saturation = leftX / boardWidth;
	Value = 1 - leftY / boardHeight;
	let bgColor = HSVtoRGB(Hue, Saturation, Value);
	resultChange(bgColor, Y);
	resColorRgb = bgColor;
	boardValueChange(resColorRgb);
}

/**
 * 透明度选择变化
 * @param e	事件
 * @param offsetX	鼠标指针在 div 元素内的偏移量
 * @param x	鼠标指针在 div 元素内的偏移量
 */
function transparencyChangeApp(e: any, offsetX?: number, x?: number) {
	let tx = offsetX ? offsetX : e.touches[0].clientX;
	let X = x ? x : tx - transparencyOffsetLeft;
	let leftX = X <= 0 ? 0 : X >= transparencyWidth ? transparencyWidth : X;
	colorTransparency.value
		?.querySelector('.color-rect')
		?.setAttribute('style', `left: ${leftX}px;`);
	transparency = leftX / transparencyWidth;
	let colorOptiy = transparency.toFixed(2);
	colorDisplay.value
		?.querySelector('.color-Block')
		.setAttribute(
			'style',
			`background: rgb(${resColorRgb.r}, ${resColorRgb.g}, ${resColorRgb.b}, ${colorOptiy});`
		);
	boardValueChange(resColorRgb);
	let colorVlaue = '';
	switch (props.colorFormat) {
		case 'hex':
			colorVlaue = toHexString({
				...resColorRgb,
				a: Number(transparency.toFixed(2)),
			});
			break;
		case 'rgb':
			colorVlaue = `rgb(${resColorRgb.r}, ${resColorRgb.g}, ${resColorRgb.b}, ${
				transparency === 1 ? transparency : transparency.toFixed(2)
			})`;
			break;
	}
	colorValue.value = colorVlaue; //十六进制
}

/**
 * 颜色条鼠标按下事件
 */
function handleBarDown(e: any) {
	barIsDragging = true;
	barOffsetX = e.offsetX;

	let X = e.clientX - barOffsetLeft;
	barChange(e, barOffsetX, X);
}

/**
 * 颜色条鼠标抬起事件
 */
function handleBarUp(e: any) {
	barIsDragging = false;
}

/**
 * 颜色条鼠标移动事件
 */
function handleBarMove(e: any) {
	if (barIsDragging) {
		let X = e.clientX - barOffsetLeft;
		barChange(e, barOffsetX, X);
	}
}

/**
 * 颜色条鼠标移出事件
 */
function handleBarOut() {
	barIsDragging = false;
}

/**
 * 颜色板鼠标按下事件
 */
function handleBoardDown(e: any) {
	boardIsDragging = true;
	boardOffsetX = e.offsetX;
	boardOffsetY = e.offsetY;

	let X = e.clientX - boardOffsetLeft;
	let Y = e.clientY - boardOffsetTop;
	pointChange(e, boardOffsetX, X, boardOffsetY, Y);
}

/**
 * 颜色板鼠标抬起事件
 */
function handleBoardUp(e: any) {
	boardIsDragging = false;
}

/**
 * 颜色板鼠标移动事件
 */
function handleBoardMove(e: any) {
	if (boardIsDragging) {
		let X = e.clientX - boardOffsetLeft;
		let Y = e.clientY - boardOffsetTop;
		pointChange(e, boardOffsetX, X, boardOffsetY, Y);
	}
}

/**
 * 颜色板鼠标移出事件
 */
function handleBoardOut() {
	boardIsDragging = false;
}

/**
 * 透明体选择条鼠标按下事件
 */
function handleTransparencyDown(e: any) {
	transparencyIssDragging = true;
	transparencyOffsetX = e.offsetX;

	let X = e.clientX - transparencyOffsetLeft;
	transparencyChange(e, transparencyOffsetX, X);
}

/**
 * 透明体选择条鼠标抬起事件
 */
function handleTransparencyUp(e: any) {
	transparencyIssDragging = false;
}

/**
 * 透明体选择条鼠标移动事件
 */
function handleTransparencyMove(e: any) {
	if (transparencyIssDragging) {
		let X = e.clientX - transparencyOffsetLeft;
		transparencyChange(e, transparencyOffsetX, X);
	}
}

/**
 * 透明体选择条鼠标移出事件
 */
function handleTransparencyOut() {
	transparencyIssDragging = false;
}

/**
 * 颜色条选取变化
 * @param e	事件
 * @param offsetX	鼠标指针在 div 元素内的偏移量
 * @param x	鼠标指针在 div 元素内的偏移量
 */
function barChange(e: any, offsetX?: any, x?: any) {
	let tx = offsetX ? offsetX : e.clientX;
	let X = x ? x : tx - barOffsetLeft;
	let leftX = X <= 0 ? 0 : X >= barWidth ? barWidth : X;
	colorBar.value
		?.querySelector('.color-rect')
		?.setAttribute('style', `left: ${leftX}px;`);
	Hue = leftX / barWidth;

	let bgColor = HSVtoRGB(Hue, 1, 1);
	colorBoard.value.style.backgroundColor = `rgb(${bgColor.r}, ${bgColor.g}, ${bgColor.b})`;
	resultChange(HSVtoRGB(Hue, Saturation, Value), 1);

	//颜色版改变
	colorPoint.value?.setAttribute(
		'style',
		`left: ${boardWidth}px; top: ${0}px;`
	);
	pointChange({}, boardWidth, boardWidth, 0, '0');
}

/**
 * 颜色板选取变化
 * @param e	事件
 * @param offsetX	鼠标指针在 div 元素内的偏移量
 * @param x	鼠标指针在 div 元素内的偏移量
 * @param offsetY	鼠标指针在 div 元素内的偏移量
 * @param y	鼠标指针在 div 元素内的偏移量
 */
function pointChange(e: any, offsetX?: any, x?: any, offsetY?: any, y?: any) {
	let tx = offsetX ? offsetX : e.clientX;
	let ty = offsetY ? offsetY : e.clientY;
	let X = x ? x : tx - boardOffsetLeft;
	let Y = y ? y : ty - boardOffsetTop / 2;
	let leftX = X <= 0 ? 0 : X >= boardWidth ? boardWidth : X; //
	let leftY = Y <= 0 ? 0 : Y >= boardHeight ? boardHeight : Y;

	colorPoint.value?.setAttribute('style', `left: ${leftX}px; top: ${leftY}px;`);
	Saturation = leftX / boardWidth;

	Value = 1 - leftY / boardHeight;
	let bgColor = HSVtoRGB(Hue, Saturation, Value);
	resultChange(bgColor, Y);
	resColorRgb = bgColor;
	boardValueChange(resColorRgb);
}

/**
 * 透明度选择变化
 * @param e	事件
 * @param offsetX	鼠标指针在 div 元素内的偏移量
 * @param x	鼠标指针在 div 元素内的偏移量
 */
function transparencyChange(e: any, offsetX?: number, x?: number) {
	let tx = offsetX ? offsetX : e.clientX;
	let X = x ? x : tx - transparencyOffsetLeft;
	let leftX = X <= 0 ? 0 : X >= transparencyWidth ? transparencyWidth : X;
	colorTransparency.value
		?.querySelector('.color-rect')
		?.setAttribute('style', `left: ${leftX}px;`);
	transparency = leftX / transparencyWidth;
	let colorOptiy = transparency.toFixed(2);
	colorDisplay.value
		?.querySelector('.color-Block')
		.setAttribute(
			'style',
			`background: rgb(${resColorRgb.r}, ${resColorRgb.g}, ${resColorRgb.b}, ${colorOptiy});`
		);
	boardValueChange(resColorRgb);
	let colorVlaue = '';
	switch (props.colorFormat) {
		case 'hex':
			colorVlaue = toHexString({
				...resColorRgb,
				a: Number(transparency.toFixed(2)),
			});
			break;
		case 'rgb':
			colorVlaue = `rgb(${resColorRgb.r}, ${resColorRgb.g}, ${resColorRgb.b}, ${
				transparency === 1 ? transparency : transparency.toFixed(2)
			})`;
			break;
	}
	colorValue.value = colorVlaue;
}

/**
 * 整理结果
 * @param resColor	结果颜色
 * @param tr	透明度
 */
function resultChange(resColor: any, tr?: number) {
	colorDisplay.value
		?.querySelector('.color-Block')
		.setAttribute(
			'style',
			`background: rgb(${resColor.r}, ${resColor.g}, ${resColor.b});`
		);
	background.value = getBackground(resColor.r, resColor.g, resColor.b);
	colorValue.value = ifHexOrRgbEmit(resColor);
}

/**
 * 判断后台是否配置颜色是十六进制还是rgb用于抛出值
 * @param resColor	结果颜色
 * @returns	十六进制或rgb
 */
const ifHexOrRgbEmit = (resColor: any) => {
	let resColorVlaue = '';
	if (props.showAlpha) {
		switch (props.colorFormat) {
			case 'hex':
				resColorVlaue = toHexString({
					...resColor,
					a: Number(transparency.toFixed(2)),
				});
				break;
			case 'rgb':
				resColorVlaue = `rgb(${resColor.r}, ${resColor.g}, ${resColor.b}, ${
					transparency === 1 ? transparency : transparency.toFixed(2)
				})`;
				break;
		}
	} else {
		switch (props.colorFormat) {
			case 'hex':
				resColorVlaue = colorRGB2hex(resColor.r, resColor.g, resColor.b);
				break;
			case 'rgb':
				resColorVlaue = `rgb(${resColor.r}, ${resColor.g}, ${resColor.b})`;
				break;
		}
	}
	return resColorVlaue;
};

/**
 * 判断颜色是十六进制还是rgb用于得到对象
 * @param resColor	结果颜色
 * @returns	rgb对象
 */
const ifHexOrRgbObject = (resColor: any) => {
	let resColorVlaue = {};
	if (resColor.indexOf('rgb') !== -1) {
		let rgb = resColor.split('(')[1].split(')')[0].split(',');

		let r = rgb[0];
		let g = rgb[1];
		let b = rgb[2];
		let a = rgb[3] ? rgb[3] : 1;
		resColorVlaue = { r, g, b, a };
	} else if (resColor.indexOf('#') !== -1) {
		resColorVlaue = hexToRgb(resColor);
	}
	return resColorVlaue;
};

/**
 * rgb字符串转数组
 * @param resColor	结果颜色
 * @param tr	透明度
 * @returns	rgb数组
 */
const handleRgbStringToArray = (resColor: any) => {
	if (resColor.indexOf('rgb') === -1) {
		return;
	}
	let rgb = resColor.split('(')[1].split(')')[0].split(',');
	return rgb;
};

/**
 * 负责处理回显位置
 * @param resColor	结果颜色
 * @param tr	透明度
 * @param type	是否是输入框传入
 */
const handleColorEcho = (resColor: IColorObj, type: boolean = true) => {
	let r = resColor.r;
	let g = resColor.g;
	let b = resColor.b;
	let a = resColor.a ? resColor.a : 1;
	let hsv = RGBtoHSV(r, g, b);

	// 颜色选择板
	colorPoint.value?.setAttribute(
		'style',
		`left: ${hsv.s * boardWidth}px; top: ${(1 - hsv.v) * boardHeight}px;`
	);
	// 颜色条
	if(type) colorBar.value
		?.querySelector('.color-rect')
		?.setAttribute('style', `left: ${hsv.h * barWidth}px;`);
	// 透明度
	colorTransparency.value
		?.querySelector('.color-rect')
		?.setAttribute('style', `left: ${resColor.a * transparencyWidth}px;`);
	colorBoard.value.style.backgroundColor = `rgb(${resColor.r}, ${resColor.g}, ${resColor.b})`;
	colorDisplay.value
		?.querySelector('.color-Block')
		.setAttribute(
			'style',
			`background: rgb(${resColor.r}, ${resColor.g}, ${resColor.b}, ${a? a: Number(transparency.toFixed(2))});`
		); // 设置颜色显示块的背景色
	background.value = getBackground(resColor.r, resColor.g, resColor.b);
};

/**
 * 16进制颜色值转rgb颜色值
 * @param hex 16进制颜色值
 * @return rgb rgb颜色值
 * @example	#ff0000 => {r: 255, g: 0, b: 0}
 */
const hexToRgb = (hex: string) => {
	let rgb = { r: 0, g: 0, b: 0, a: 1 };
	let result: any = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
	try {
		rgb.r = parseInt(result[1], 16);
		rgb.g = parseInt(result[2], 16);
		rgb.b = parseInt(result[3], 16);
	} catch (e) {
	}
	return rgb;
};

/**
 * 255颜色值转16进制颜色值
 * @param n 255颜色值
 * @return hex 16进制颜色值
 */
const toHex = (n: number) => `${n > 15 ? '' : 0}${n.toString(16)}`;

/**
 * HSV颜色值转换为RGB颜色值
 * H, S, V取值范围在 [0, 1] 之间
 * @param h 色相
 * @param s 饱和度
 * @param v 亮度
 * @return rgb 颜色值
 */
function HSVtoRGB(h: any, s: number, v: number) {
	let r: number, g: number, b: number, i, f, p, q, t;
	if (arguments.length === 1) {
		(s = h.s), (v = h.v), (h = h.h);
	}
	i = Math.floor(h * 6);
	f = h * 6 - i;
	p = v * (1 - s);
	q = v * (1 - f * s);
	t = v * (1 - (1 - f) * s);
	switch (i % 6) {
		case 0:
			(r = v), (g = t), (b = p);
			break;
		case 1:
			(r = q), (g = v), (b = p);
			break;
		case 2:
			(r = p), (g = v), (b = t);
			break;
		case 3:
			(r = p), (g = q), (b = v);
			break;
		case 4:
			(r = t), (g = p), (b = v);
			break;
		case 5:
			(r = v), (g = p), (b = q);
			break;
	}
	return {
		r: Math.round(r * 255),
		g: Math.round(g * 255),
		b: Math.round(b * 255),
	};
}

/**
 * RGB颜色值转换为HSV颜色值
 * @param r 红色值
 * @param g 绿色值
 * @param b 蓝色值
 * @return hsv 颜色值
 */
function RGBtoHSV(r: number, g: number, b: number) {
	r = r / 255;
	g = g / 255;
	b = b / 255;

	let max = Math.max(r, g, b);
	let min = Math.min(r, g, b);
	let h: any,
		s,
		v = max;

	let d = max - min;
	s = max == 0 ? 0 : d / max;

	if (max == min) {
		h = 0;
	} else {
		switch (max) {
			case r:
				h = (g - b) / d + (g < b ? 6 : 0);
				break;
			case g:
				h = (b - r) / d + 2;
				break;
			case b:
				h = (r - g) / d + 4;
				break;
		}
		h /= 6;
	}

	return {
		h: h,
		s: s,
		v: v,
	};
}

/**
 * rgb转十六进制颜色
 * @param r 红色值
 * @param g 绿色值
 * @param b 蓝色值
 * @returns hex 十六进制颜色值
 */
function colorRGB2hex(r: any, g: any, b: any) {
	let hex = '#' + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1);
	return hex;
}

/**
 * 获取渐变背景
 * @param r 红色值
 * @param g 绿色值
 * @param b 蓝色值
 * @param t 透明度
 * @return background 渐变背景
 */
function getBackground(r: number, g: number, b: number, t?: number) {
	return `linear-gradient(to right, rgba(${r}, ${g}, ${b}, ${
		t ? t : '0'
	}) 0%, rgba(${r}, ${g}, ${b}, ${t ? t : '1'}) 100%)`;
}

/**
 * 颜色对象转化为16进制颜色字符串
 * @param colorObj 颜色对象
 * @returns 16进制颜色字符串
 */
const toHexString = (colorObj: IColorObj) => {
	const { r, g, b, a = 1 } = colorObj;
	return `#${toHex(r)}${toHex(g)}${toHex(b)}${
		a === 1 ? '' : toHex(Math.floor(a * 255))
	}`;
};

/**
 * 判断是否启用了透明度选择，是则对传输透明度并定位到对应位置
 * @param colorValue 颜色值
 * @param type 是否是输入框输入
 */
const ifShowAlphaColorEcho = (colorValue: string, type: boolean)=> {	
	let resColorEmit: IColorObj | any; 
	if(props.showAlpha){
		if (colorValue.indexOf('#') !== -1 && isHexadecimal(colorValue)) {
			try {
				resColorEmit = hexToRgb(colorValue);
				handleColorEcho({...resColorEmit}, type);
			} catch (error) {
			}
		}else if(colorValue.indexOf('rgb') !== -1){
			resColorEmit = handleRgbStringToArray(colorValue);
			handleColorEcho({
				r: resColorEmit[0],
				g: resColorEmit[1],
				b: resColorEmit[2],
				a: resColorEmit[3],
			}, type);
		}
	}else{
		if (colorValue.indexOf('#') !== -1 && isHexadecimal(colorValue)) {
			try {
				resColorEmit = hexToRgb(colorValue);
				handleColorEcho({...resColorEmit}, type);
			} catch (error) {
			}
		}else if(colorValue.indexOf('rgb') !== -1){
			resColorEmit = handleRgbStringToArray(colorValue);
			handleColorEcho({
				r: resColorEmit[0],
				g: resColorEmit[1],
				b: resColorEmit[2],
			}, type);
		}
	}
};

/**
 * 判断是否为16进制颜色
 * @param str
 * @returns
 */
const isHexadecimal = (str: string) => {
	let reg = /^[0-9a-fA-F]+$/;
	return reg.test(str.replace('#', ''));
};

/**
 * 抛值时组合颜色
 * @param color
 * @returns	返回Rgb颜色值
 */
const handleColorEmit = (color: any) => {
	let resColorEmit = `rgb(${resColorRgb.r}, ${resColorRgb.g}, ${resColorRgb.b})`;
	if (props.colorFormat === 'hex') {
		resColorEmit = toHexString({ ...color, a: transparency });
	} else if (props.showAlpha) {
		resColorEmit = `rgb(${color.r}, ${color.g}, ${color.b}, ${
			transparency === 1 ? 1 : transparency.toFixed(2)
		})`;
	}
	return resColorEmit;
};


/**
 * 关闭时抛值
 * @ifShowAlphaColorEcho 如果有透明度则对透明度选取位置定位
 */
 const handleClose = () => {
	colorValue.value = colorNumber;
	ifShowAlphaColorEcho(colorValue.value);
	emit('wrapperClose', colorNumber);
};

/**
 * 点击确定时抛值
 */
const handleDetermine = () => {
	colorNumber = colorValue.value;
	ifShowAlphaColorEcho(colorValue.value);
	emit('wrapperDetermineChange', colorValue.value, 'arrow-down');
};

/**
 * 点击颜色板时抛值
 * @param color
 */
const boardValueChange = (color: any) => {
	emit('wrapperChange', handleColorEmit(color));
};

watch(() => colorValue.value, () => {
	ifShowAlphaColorEcho(colorValue.value, false);
});

onMounted(() => {
	init();
});
</script>
